package com.inexas.cu.client.mvp;

import java.util.*;

public class PropertyImpl<T> extends MemberImpl implements Property<T> {
	private T value;
	private List<ValidationError> validationErrors;

	public PropertyImpl(String key, T value) {
		super(key);
		this.value = value;
	}

	public PropertyImpl(String key) {
		super(key);
	}

	/* (non-Javadoc)
     * @see com.inexas.cu.client.mvp.Property#getValue()
     */
	public T getValue() {
		return value;
	}

	/* (non-Javadoc)
     * @see com.inexas.cu.client.mvp.Property#setValue(com.inexas.cu.client.mvp.Source, T)
     */
	public void setValue(Source source, T value) {
		// Observable will check for null source

		// Avoid firing unless there has been a change...
		final boolean change;
		if(value == null) {
			change = this.value != null;
		} else {
			change = !value.equals(this.value);
		}
		if(change) {
			this.value = value;
			fire(source, new ChangeNotifcation<T>(value));
		}
	}

	/* (non-Javadoc)
     * @see com.inexas.cu.client.mvp.Property#setValidationErrors(com.inexas.cu.client.mvp.Source, java.util.List)
     */
	public void setValidationErrors(Source source, List<ValidationError> validationErrors) {
		assert validationErrors == null || validationErrors.size() > 0 :
			"Please pass me a null if there are no validation errors";
		
		// Only on a change...
		final boolean change;
		if(validationErrors == null) {
			change = this.validationErrors != null;
		} else {
			change = !validationErrors.equals(this.validationErrors);
		}
		if(change) {
			this.validationErrors = validationErrors;
			fire(source, new ValidationChangeNotification(validationErrors));
		}
    }

	/* (non-Javadoc)
     * @see com.inexas.cu.client.mvp.Property#getValidationErrors()
     */
	public List<ValidationError> getValidationErrors() {
    	return validationErrors;
    }
	
	/* (non-Javadoc)
     * @see com.inexas.cu.client.mvp.Property#isValid()
     */
	public boolean isValid() {
		return validationErrors == null;
	}

}
